<template>
  <n-drawer v-model:show="active" v-bind="getBindValue">
    <n-drawer-content>
      <template #header v-if="getProps.showHeader&&$slots.header">
        <slot name="header"></slot>
      </template>
      <template #header v-if="getProps.showHeader&&!$slots.header">
        <div class="drawer-header">
          {{ props.title }}
        </div>
      </template>
      <slot name="default"></slot>

      <template v-if="showFooter" #footer>
        <template v-if="$slots.footer"> <slot name="footer"></slot> </template>
        <template v-else>
          <n-space v-if="newFootBtns.length">
            <n-button
              v-for="(item, index) in newFootBtns"
              :key="index"
              v-bind="item.bind"
              :loading="loadings[index]"
            >
              <template v-if="item.icon" #icon>
                <n-icon :component="item.icon" />
              </template>
              {{ item.label }}
            </n-button>
          </n-space>
          <n-space v-else>
            <n-button @click="close">{{ getProps.negativeText }}</n-button>
            <n-button
              v-if="showConfirm"
              type="primary"
              :loading="subLoading"
              @click="handleSubmit"
              >{{ getProps.positiveText }}</n-button
            >
          </n-space>
        </template>
      </template>
    </n-drawer-content>
  </n-drawer>
</template>

<script lang="ts" setup name="Dpdrawer">
  import { useAttrs } from 'vue';
  import { SizeEnum, footBtnsItem } from '../index.d';
  import { t } from '@/i18n';

  type Props = {
    size?: keyof typeof SizeEnum;
    width?: string | number;
    title?: string;
    showConfirm?: boolean;
    showFooter?: boolean;
    footBtns?: footBtnsItem[];
    negativeText?: string;
    positiveText?: string;
    showHeader?: boolean;
  };

  const attrs = useAttrs();

  const props = withDefaults(defineProps<Props>(), {
    width: '',
    title: '',
    size: 'medium',
    showConfirm: true,
    showFooter: true,
    footBtns: undefined,
    negativeText: '',
    positiveText: '',
    showHeader: true,
  });
  const propsRef = ref<Partial<Props> | null>(null);
  const getProps = computed(() => {
    return {
      ...props,
      negativeText: t('common.button.cancel'),
      positiveText: t('common.button.save'),
      ...unref(propsRef),
    };
  });

  const getBindValue = computed(() => {
    const obj = {
      'close-on-esc': false,
      'mask-closable': true,
      ...attrs,
      ...unref(getProps),
    };

    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { width, size, title, ...restObj } = obj;
    // 剔除 title, 重置 size
    restObj['width'] = width ? width : size ? SizeEnum[size] : '900';
    return restObj;
  });

  const loadings = ref<boolean[]>([]);
  const newFootBtns: any = ref([]);
  watch(
    () => props.footBtns,
    () => {
      const { footBtns } = props;
      loadings.value = new Array(footBtns?.length).fill(false);
      newFootBtns.value = btnsFormat(footBtns);
    },
  );

  const btnsFormat = (footBtns) => {
    return footBtns.map((btn, index) => {
      const { bind } = btn;
      return {
        ...btn,
        bind: {
          ...bind,
          onClick: (event: MouseEvent) => {
            loadings.value[index] = true;
            bind.onClick(
              (loading: boolean) => {
                loadings.value[index] = loading ?? true;
              },
              btn,
              event,
            );
          },
        },
      };
    });
  };

  // 弹窗事件
  const active = ref(false);
  const open = (props: Props) => {
    propsRef.value = props;
    active.value = true;
  };
  const close = () => {
    active.value = false;
    emit('on-close');
  };
  // 按钮事件
  const subLoading = ref(false);
  const setSubLoading = (status: boolean) => {
    subLoading.value = status;
  };
  const handleSubmit = () => {
    subLoading.value = true;
    emit('confirm', setSubLoading);
  };
  //
  const emit = defineEmits(['on-close', 'confirm']);
  defineExpose({ open, close });
</script>
<style lang="less" scoped>
  .drawer-header {
    position: relative;
  }
</style>
